package com.bluegalaxy.nhb.snservice.service.ck.impl;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bluegalaxy.nhb.service.AssembleService;
import com.bluegalaxy.nhb.snservice.common.utils.DateUtil;
import com.bluegalaxy.nhb.snservice.common.utils.SqlTableUtil;
import com.bluegalaxy.nhb.snservice.common.utils.StringUtil;
import com.bluegalaxy.nhb.snservice.core.util.ChartUtil;
import com.bluegalaxy.nhb.snservice.dao.*;
import com.bluegalaxy.nhb.snservice.domain.constant.CkConstant;
import com.bluegalaxy.nhb.snservice.domain.enums.BaseUserEnum;
import com.bluegalaxy.nhb.snservice.domain.vo.BootstrapTablePage;
import com.bluegalaxy.nhb.snservice.domain.vo.api.R;
import com.bluegalaxy.nhb.snservice.domain.vo.api.ck.PredictUserResVO;
import com.bluegalaxy.nhb.snservice.domain.vo.api.ck.UserPortraitTemplateItems;
import com.bluegalaxy.nhb.snservice.service.ck.UserPortraitService;
import com.bluegalaxy.nhb.snservice.service.ck.UserTagsService;
import com.bluegalaxy.nhb.snservice.service.execute.ExecuteService;
import com.bluegalaxy.nhb.snservice.service.execute.XxService;
//import com.bluegalaxy.nhb.sql.AssembleSql;
import com.github.pagehelper.PageHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("UserPortraitService")
public class UserPortraitServiceImpl implements UserPortraitService {
    private static Log log = LogFactory.getLog(UserPortraitServiceImpl.class);

    @Autowired
    private UserGroupMapper userGroupMapper;
    @Autowired
    private UserPortraitMapper userPortraitMapper;
    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private ExecuteService executeService;
    @Autowired
    private XxService xxService;

    @Resource
    private AssembleService assembleService;


    @Override
    public R findUsersById(JSONObject param) {
        String tableId = param.getString("tableId");
        if (StringUtil.isEmpty(tableId)){
            return R.fail("");
        }

        int current = param.getInteger("current")==null? 0 :param.getInteger("current");
        int pageSize = param.getInteger("pageSize")==null? 10 :param.getInteger("pageSize");
//        current = current == 1?0:current;
        int startPage = current == 0?0:(current - 1) * pageSize;

        List<Map<String,Object>> attrList = xxService.selectUserAttribute();
//        PageAutoDialect.registerDialectAlias("clickhouse", MySqlDialect.class);
        PageHelper.startPage(current,pageSize);
        List<Map<String,Object>> list = userPortraitMapper.selectByTableName(tableId,startPage,pageSize,attrList);
        Integer totalCount = userPortraitMapper.countByTableName(tableId);
//        PageInfo<Map<String,Object>> pageInfo = new PageInfo<>(list);
        BootstrapTablePage tablePage = new BootstrapTablePage();
        tablePage.setRows(list);
        tablePage.setTotal(totalCount.longValue());
        return R.data(tablePage);
    }

    @Override
    public R createUsers(JSONObject param) {
        String tableName = StringUtil.isEmpty(param.getString("tableId"))?SqlTableUtil.getTagName():param.getString("tableId");
        String tableType = StringUtil.isEmpty(param.getString("tableType"))?"ADD":param.getString("tableType");
        String dt = StringUtil.isEmpty(param.getString("dt"))? DateUtil.getNowYYYYMMDD() :param.getString("dt");
        if ("ADD".equals(tableType)){
            boolean flag = executeService.createTable(tableName, BaseUserEnum.PORTRAIT.name());
            if (!flag){
                return R.fail("创建画像错误");
            }
        }
        int dtCount = userPortraitMapper.countByDt(tableName,dt);
        if (dtCount > 0){
            return R.fail("该日期【"+dt+"】下用户数据已存在。");
        }
        String sql = assembleService.assembleSql(param, CkConstant.ARRAY);
//        String sql = AssembleSql.assembleSql(param, CkConstant.ARRAY);
        List<String> list = userGroupMapper.selectBySql(sql);
        if (!list.isEmpty()){
            userPortraitMapper.insertBatch(tableName,list,dt);
        }

        return R.data(list.size());
    }


    @Override
    public R countUsers(JSONObject param) {
        String sql = assembleService.assembleSql(param, CkConstant.COUNT);
        int result = userGroupMapper.countBySql(sql);
        return R.data(result);
    }

    @Override
    public R findPredictUsers(JSONObject param) {

        PredictUserResVO resVO = new PredictUserResVO();
        Integer totalUserNum = usersMapper.count();
        resVO.setMainTotalNum(totalUserNum);
        resVO.setControlTotalNum(totalUserNum);

        String controlGroupId = StringUtil.isEmpty(param.getString("controlGroupId"))?"":param.getString("controlGroupId");
        String itemArrayStr = param.getString("portraitTemplateItems");
        JSONArray itemArray = param.getJSONArray("portraitTemplateItems");
        List<UserPortraitTemplateItems> portraitItems = null;

        String sql = assembleService.assembleSql(param, CkConstant.ARRAY);

        Map<String,Object> paramMap = new HashMap<>();
        String userFlag = null;
        String eventFlag = null;
        List<String> uList = new ArrayList<>();
        List<String> eList = new ArrayList<>();

        if (StringUtil.isNotEmpty(itemArrayStr)){
            portraitItems = itemArray.toJavaList(UserPortraitTemplateItems.class);
            Map<String, List<UserPortraitTemplateItems>> rrMap = portraitItems.stream().collect(
                    Collectors.groupingBy(a -> a.getParamField1()));
            log.info("表 分组后："+rrMap.size());
            for (Map.Entry<String, List<UserPortraitTemplateItems>> m : rrMap.entrySet()) {
                String tableKey = m.getKey();
                if (StringUtil.isEmpty(tableKey)){
                    continue;
                }
                if (tableKey.contains(CkConstant.table_events)){
                    eventFlag = "Y";
                    m.getValue().stream().forEach(item ->{
                        eList.add(item.getParamField2());
                    });

                }
                if (tableKey.contains(CkConstant.table_users)){
                    userFlag = "Y";
                    m.getValue().stream().forEach(item ->{
                        uList.add(item.getParamField2());
                    });
                }
            }
        }

        paramMap.put("paramSql",sql);
        paramMap.put("userFlag",userFlag);
        paramMap.put("eventFlag",eventFlag);
        paramMap.put("uList",uList);
        paramMap.put("eList",eList);
        paramMap.put("controlGroupId",controlGroupId);
        List<Map<String,Object>> result = userPortraitMapper.selectPredictUsers(paramMap);

        if (portraitItems != null){
            resVO.setMainNum(result.size());
            BigDecimal numBig = new BigDecimal(resVO.getMainNum() * 100);
            BigDecimal paramBig = new BigDecimal(resVO.getMainTotalNum());
            BigDecimal scale = numBig.divide(paramBig,1,BigDecimal.ROUND_HALF_UP);
            if (scale.compareTo(BigDecimal.valueOf(100)) > 0){
                scale = BigDecimal.valueOf(100);
            }
            resVO.setMainScale(scale);

            List<UserPortraitTemplateItems> mainItemList = new ArrayList<>();
            for (UserPortraitTemplateItems items : portraitItems){
                if(result.size() > 0){
                    UserPortraitTemplateItems resItem = new UserPortraitTemplateItems();
                    BeanUtils.copyProperties(items,resItem);
                    ChartUtil.getChart(result,resItem);
                    mainItemList.add(resItem);
                }else{
                    mainItemList.add(items);
                }
            }
            resVO.setMainItems(mainItemList);
        }

        if (StringUtil.isNotEmpty(controlGroupId)){
            StringBuffer controlBuffer = new StringBuffer();
            controlBuffer.append("select u_id as distinct_id from " + controlGroupId +
                    "               where `dt` = (select max(`dt`) from "+controlGroupId+" ) ");
            paramMap.put("paramSql",controlBuffer.toString());

            List<Map<String,Object>> controlResult = userPortraitMapper.selectPredictUsers(paramMap);
            if (portraitItems != null){
                resVO.setControlNum(controlResult.size());
                BigDecimal numBig = new BigDecimal(resVO.getControlNum() * 100);
                BigDecimal paramBig = new BigDecimal(resVO.getControlTotalNum());
                BigDecimal scale = numBig.divide(paramBig,1,BigDecimal.ROUND_HALF_UP);
                if (scale.compareTo(BigDecimal.valueOf(100)) > 0){
                    scale = BigDecimal.valueOf(100);
                }
                resVO.setControlScale(scale);
                List<UserPortraitTemplateItems> resItemList = new ArrayList<>();
                for (UserPortraitTemplateItems items : portraitItems){
                    if(controlResult.size() > 0){
                        UserPortraitTemplateItems resItem = new UserPortraitTemplateItems();
                        BeanUtils.copyProperties(items,resItem);
                        ChartUtil.getChart(controlResult,resItem);
                        resItemList.add(resItem);
                    }else{
                        resItemList.add(items);
                    }
                }

                resVO.setControlItems(resItemList);
            }
        }

        return R.data(resVO);
    }



}
